4章 不変の活用
4.1 再代入
再代入は変数の意味が変わり、推測を困難にします。(p.85)
変数tmpに代入された値がコロコロ変わる例
対策:finalを付けて不変にする
ローカル変数
引数
finalを付ける(=再代入しない)=不変にする なのか?
『スラスラわかるJava』(変数にfinalを付ける例はなし)
finalが付いたクラスは継承できない
finalが付いたメソッドはオーバーライドできない
ミノ駆動本と同様の意図でローカル変数をFinalで型ヒントできる(再代入しない)
関数の引数には使えない(2022/08 Python 3.10)
引数を変更したい場合は、不変なローカル変数を用意し、そのローカル変数に変更値を代入する実装にします。(p.88)
Pythonicと両立できなさそうな印象
str | list[str]を引数に受け取る関数。strを受け取ったら再代入してlist[str]に変えるような書き方
4.2 可変がもたらす意図せぬ影響
1. 使い回し
a = b = []と同様と思われる
👉使い回しをやめる
2. 可変インスタンスの操作
別スレッド(競合?)
副作用:「主作用以外に状態変更」
主作用:「値を返すこと」(返り値が主作用と理解)
副作用は関数の外部に影響を与える
👉インスタンス変数を不変にする(final)
新たにインスタンス生成して使うことになる
引数で状態を受け取り、状態変更せず、値を返すだけの関数が理想です (p.97)
クリーンアーキテクチャのようなIOとアプリケーションロジックを分離し、アプリケーションロジック側を想像した
reinForceつづりがちょっと気になる(reinforceで一語)
4.3 不変と可変の取り扱い方針
標準は不変
間違った使い方ができない構造にする、フールプルーフの立場 (p.102)
val, const, Rustのデフォルトと再代入できない流れ
Clean Architecture、関数型言語のところで言及
不変では値の変更はインスタンス生成
大量の値の変更が必要でパフォーマンスに問題が生じるならば可変にするという立場
可変にする場合は正しく状態変更できるメソッド(ミューテーター)を
コード外とのやりとりを局所化するテクニックが人気です (p.107)
リポジトリパターンのクラス内にデータベース関連のロジックが隔離される (p.108 注4)
可変・不変の定義が一般よりやや広いかも
可変には変数の値を変更するも含む?(4章冒頭)
可変と再代入は一般に同じ?
オブジェクトの変更以外に変数の再代入について可変と言っている